<!-- 可以滚动的横向菜单 -->
<template>
	<div v-if="isInitial" id="initial" style="width: 100%;height: 10px;"/>
	<div v-else-if="showAll === 2" :style="[{width: totalWidth ? (totalWidth + 'px') : 'auto', display: 'flex', alignItems: 'center', flexWrap: 'wrap'}]">
		<div style="margin: 0 5px;text-align: center;line-height: 30px;" v-for="(item, index) in menuList.concat({text: '退出'})" v-if="show(item)" :key="index" @click="onClick(index, true)">
			<div v-if="index === menuList.length" @click.stop="e => showAll = true">
				<slot name="exit">
					<div class="center" style="height: 30px; width: auto; aspect-ratio: 1;">
						<IconFont :type="exitIcon" :color="themetool.color.warn"/>
					</div>
				</slot>
			</div>
			<slot v-else name="item">
				<text :style="[{
					fontSize: getFontSize, color: index === currentIndex ? (activeColor || themetool.color.main) : (normalColor || themetool.color.light)
				}, scrollLine ? {
					paddingBottom: '3px',
					borderBottom: `${index === currentIndex ? 1 : 0}px solid ${activeColor || themetool.color.main}`, 
				} : {}]">{{lang(itemShow(item))}}</text>
			</slot>
		</div>
	</div>
	<div v-else :style="[{display: 'flex', alignItems: 'center', width: totalWidth ? (totalWidth + 'px') : 'auto', height: scrollHeight + 'px'}]">
		<scroll-view class="scroll-view" scroll-x scroll-with-animation :scroll-left="scrollLeft" :style="[{width: showAll ? `calc(100% - 35px)` : '100%', marginLeft: '5px'}]">
		    <div v-for="(item, index) in menuList" v-if="show(item)" :id="`menu-${index}`" :key="index" class="center" :style="[{display: 'inline-block', margin: '0 5px', height: parseFloat(scrollHeight) - 1 + 'px'}]" @click="onClick(index, false)">
				<slot name="item">
					<text :style="[{
						fontSize: getFontSize, color: index === currentIndex ? (activeColor || themetool.color.main) : (normalColor || themetool.color.light)
					}, scrollLine ? {
						paddingBottom: '3px',
						borderBottom: `${index === currentIndex ? 1 : 0}px solid ${activeColor || themetool.color.main}`, 
					} : {}]">{{lang(itemShow(item))}}</text>
				</slot>
		    </div>
		</scroll-view>
		<slot name="right">
			<div v-if="showAll" class="center" :style="[{width: rightWidth + 'px', marginBottom:  5 + (scrollLine ? 4 : 0) + 'px'}]">
				<IconFont :type="allIcon" size="20" @click="e => showAll = 2"/>
			</div>
		</slot>
	</div>
</template>

<script>
	
	import base from '@/components/index.vue'
	
	
	/**
	 * 一般用于横向滚动的菜单
	 */
	export default {
		extends: base,
		/**
		 * change：第一个回调参数是value对应的值（有两种是角标的情况：1，valueIsIndex为true，并且value是Number类型；2，menuList中value字段不存在）；第二个参数确定是menuList的值内容或对象；第三个参数确定是角标
		 * click：第一个回调参数确定就是角标；第二个参数确定是menuList的值内容或对象
		 */
		emits: ['change', 'click'],
		props: {
			// 滚动数据。内部元素可以是字符串，也可以是对象。对象默认是text，value。如需映射，请指定map
			menuList: Array,
			/**
			 * 当前选择项 - 默认是指当前项的值，而非当前项的角标。
			 * 
			 * 	若是角标，可使用current以及@click事件回调；
			 * 	也可以以通过指定valueIsIndex为true，并且value是Number类型来当做角标控制
			 * 
			 * 在menuList的长度内的值或者-1，就是表示第几项，其它情况表示value
			 */
			value: [Number, String],
			// value是否为角标
			valueIsIndex: Boolean,
			// 当前项角标。value优先级大于current
			current: Number,
			// 字体大小
			fontSize: [String, Number],
			// 选中的颜色值。默认主题颜色
			activeColor: {
				type: String,
				// default: 'cornflowerblue'
			},
			// 未选中的颜色值。默认主题light
			normalColor: {
				type: String,
				// default: '#666'
			},
			// 是否显示底部横线
			scrollLine: {
				type: Boolean,
				default: true
			},
			// 全部的图标
			allIcon: {
				type: String,
				default: 'zhankai'
			},
			// 退出全部的图标
			exitIcon: {
				type: String,
				default: 'close'
			},
			// 映射规则
			map: {
				type: Object,
				default: () => {
					return {
						text: 'text',
						value: 'value',
						disable: 'disable'
					}
				}
			},
			scrollHeight: {
				type: [String, Number],
				default: 36
			},
			// 微信小程序中如果样式是100%，会被无限撑大，需指定具体的数值
			scrollWidth: [String, Number],
			// 右侧全部图标的宽度
			rightWidth: {
				type: [String, Number],
				default: 30
			},
			// 是否不处理居中
			unhandle: Boolean
		},
		watch: {
			isInitial(value) {
				if (!value) {
					// 滚动时，是否显示全部
					this.$nextTick(() => {
						this.core.component.query(`#menu-${this.menuList.length - 1}`, this).then(res => {
							const {left, width} = res
							if (left + width < this.totalWidth) {
								this.showAll = false
								this.maxWidth = this.totalWidth
							} else {
								this.showAll = true
								this.maxWidth = this.totalWidth - this.rightWidth
							}
						})
					})
					// 获取显示角标
					let currentIndex = this.getCurrentIndex(this.value)
					if (currentIndex === -1) {
						// this.current的优先级低于this.value
						currentIndex = this.current
					}
					if (currentIndex >= 0) {
						this.currentIndex = currentIndex
					}
				}
			},
			current(value) {
				this.currentIndex = value
			},
			currentIndex(value) {
				this.emit(value)
				if (!this.unhandle) {
					this.handleScrollLeft()
				}
			}
		},
		data() {
			return {
				// 初始化获取最大的宽度
				isInitial: true,
				/**
				 * 是否显示全部
				 * false：不显示该按钮文字
				 * true或1：显示该按钮文字
				 * 2：显示全部的菜单
				 */
				showAll: false,
				// 当前选择了第几项
				currentIndex: 0,
				// 滚动器滚动的距离
				scrollLeft: 0,
				// 总宽度
				totalWidth: 0,
				// scrollView的宽度
				maxWidth: 0
			}
		},
		computed: {
			getFontSize() {
				var {fontSize} = this
				if (!fontSize) {
					fontSize = 16
				}
				if (typeof(fontSize) === 'number') {
					fontSize += 'px'
				}
				return fontSize
			},
			themetool() {
				return this.core.theme
			}
		},
		mounted() {
			this.initial()
		},
		methods: {
			initial() {
				if (this.scrollWidth) {
					this.totalWidth = parseFloat(this.scrollWidth)
					this.isInitial = false
				} else {
					this.core.component.query('#initial').then(res => {
						this.totalWidth = res.width
						this.isInitial = false
					})
				}
			},
			
			// 通过value获取当前索引值
			getCurrentIndex(value) {
				if (this.valueIsIndex && value >= 0) {
					return parseInt(value)
				}
				if (value || value === '' || value === 0) {
					for (let i = 0; i < this.menuList.length; i++) {
						const item = this.menuList[i]
						if (typeof(item) === 'string') {
							if (item === value) {
								return i
							}
						} else {
							if (item[this.map.value || 'value'] === value) {
								return i
							}
						}
					}
				}
				return -1
			},
			
			/**
			 * 处理当前元素的位置
			 * 已知条件：该组件的宽度maxWidth，该元素的位置offsetLeft
			 * 当offsetLeft超过maxWidth的一半时，就要滚动，使其居中
			 */
			handleScrollLeft() {
				const {maxWidth, scrollLeft = 0} = this
				this.$nextTick(() => {
					this.core.component.query(`#menu-${this.currentIndex}`, this).then(res => {
						const {left, width} = res
						res = left + scrollLeft - (maxWidth - width) * 0.5
						if (res > 0) {
							// 让其居中
							this.scrollLeft = res
						} else {
							this.scrollLeft = 0
						}
					})
				})
			},
			
			// 是否显示当前项
			show(item) {
				if (typeof(item) === 'string') {
					return true
				}
				return !item[this.map.disable || 'disable']
			},
			
			// 当前项显示的内容
			itemShow(item) {
				if (typeof(item) === 'string') {
					return item
				}
				return item[this.map.text || 'text'] || ''
			},
			
			// 点击事件
			onClick(index, forAll) {
				if (this.currentIndex !== index) {
					this.currentIndex = index
					if (forAll) {
						this.showAll = true
					}
				}
			},
			
			// 点击事件的回调处理
			emit(index) {
				if (index > -1 && index < this.menuList.length) {
					var value
					if (this.valueIsIndex && this.value >= 0) {
						value = index
					} else {
						value = this.menuList[index]
						if (typeof(value) === 'string') {
							
						} else {
							if (value) {
								value = value[this.map.value || 'value']
							}
						}
					}
					this.$emit('input', value)
					this.$emit('click', index, this.menuList[index])
					this.$emit('change', value, this.menuList[index], index)
				}
			}
		}
	}
</script>

<style>
	.scroll-view {
		width: 100%;
		white-space: nowrap;
		scrollbar-width: none; /* 对于微信小程序 */
		/* #ifdef H5 */
		::-webkit-scrollbar { /* 对于web */
		  display: none; /* 隐藏滚动条 */
		  // width: 0 !important; /* 可选，滚动条宽度为0 */
		  // height: 0 !important; /* 滚动条高度为0 */
		  // -webkit-appearance: none; /* 移除默认滚动条样式 */
		  // background: transparent; /* 背景透明 */
		}
		/* #endif */
	}
</style>